<?
//defined('_ACCESS') or die( 'Direct Access to this location is not allowed.' );
//defined('_LOCATION') or die( 'Direct Access to this location is not allowed.' );

class graphite
{
/* filename image is saved as */
public $filename = "graphite.gif";

/* Size of the gif */
public $width = 600;
public $height = 450;

/* Text labels describing the x and y axis */
public $x_axis_label = "x_axis";
public $y_axis_label = "y_axis";

/* The array of integers data to be plotted */
public $data = array();

/* Text labels on the x axis corresponding to each element in $data */
public $data_lables = array();

/* Text labels on the y axis describing the range of the data */
public $y_lables = array();

/* Default font to use when printing */
public $font_size = 10;
public $font_name = 'cour';

/* Default colors */
public $background_color = 0;
public $border_color = 0;
public $graph_color = 0;

/*
 * Private variables (only in thought)
 */

/* image handle */
protected $image;

/* The virtual range within that the data is displayed on the graph */
protected $y_range_pos;
protected $y_range_neg;

/* cooridnate the x axis is graphed */
protected $x_axis;

/* Width and Height in pixels of the plotting area */
protected $plotarea_width;
protected $plotarea_height;

/* Array of Plotted data  in (x,y) format */
protected $plotted_data = array();

	/*
	 * Defacto Data class constructor
	 */
	function init()
	{		
		/* Create image handle */
		$this->image = imagecreate($this->width, $this->height);
				
		/* Allocate Standard Colors */
		$this->background_color = $this->allocColor(255, 255, 255);
		$this->border_color = $this->allocColor(0, 0, 0);
		$this->graph_color = $this->allocColor(0, 0, 255);
				
		/* Find longest string of the y_lables */
		$coord = imagettfbbox($this->font_size, 0, $this->font_name, max($this->y_lables));				
		$y_lables_w = $coord[2] - $coord[0];	
		//$y_lables_h = $coord[1] - $coord[7];
		$coord = imagettfbbox($this->font_size, 90, $this->font_name, $this->y_axis_label);
		$y_axis_lable_w = abs($coord[0] - $coord[6]);
		//************************************************
		$this->plotarea_width = $this->width - $y_lables_w - $y_axis_lable_w - 3 * 5;		
		
		$coord = imagettfbbox($this->font_size, 0, $this->font_name, $this->x_axis_label);				
		$x_axis_lable_h = abs($coord[1] - $coord[7]);		
		$coord = imagettfbbox($this->font_size, 0, $this->font_name, $this->data_lables[0]);				
		$x_lables_h = 1.5 * abs($coord[1] - $coord[7]);
		//**********************************************			
		$this->plotarea_height = $this->height - $x_lables_h - $x_axis_lable_h - 3 * 5;
	
		/*  Set the display range */		
		if(!isset($this->y_range_pos))
		{
			$this->y_range_pos = max($this->y_lables);
		}
		
		if(!isset($this->y_range_neg))
		{
			$this->y_range_neg = abs(min($this->y_lables));
		}
		
		/* Calculate where to graph the x axis */
		$this->x_axis = ($this->y_range_pos / ($this->y_range_pos + $this->y_range_neg)) * $this->plotarea_height;
		
		/* Draw Background */
		imagefilledrectangle($this->image,
		0,0,$this->width - 1, $this->height - 1,
		$this->background_color);		
		
		$coord = imagettfbbox($this->font_size,// размер шрифта
								90,          // угол наклона шрифта (0 = не наклоняем)
								$this->font_name,  // имя шрифта, а если точнее, ttf-файла
								$this->y_axis_label	       // собственно, текст
	    );    
		/* 
		(x,y):	
		(6,7)           (4,5)
		+---------------+
		|Всем привет! :)|
		+---------------+
		(0,1)           (2,3)	
		*/     
		$width = $coord[2] - $coord[0];
		$height = $coord[1] - $coord[7];
			
		/* Draw y axis label */
		//imagestringup($this->image, $this->font,
		//10, ($this->plotarea_height / 2) + (strlen($this->y_axis_label) * 3.5), $this->y_axis_label,
		//$this->border_color);
		//imagestringup	
		imagettftext(
					$this->image,
					$this->font_size,
					90,
					
					$width + 15, 
					($this->plotarea_height / 2) + (strlen($this->y_axis_label) * 3.5),				
					
					$this->border_color,
					$this->font_name,
					$this->y_axis_label				
					);	
	
		/* Draw x axis label */	
		//imagestring($this->image, $this->font,
		//(($this->width - $this->plotarea_width) + $this->plotarea_width / 2) - (strlen($this->x_axis_label) * 3.5),
		//$this->height - 25,	$this->x_axis_label, $this->border_color);
		
		
		imagettftext(
					$this->image,				
					$this->font_size,
					0,
					(($this->width - $this->plotarea_width) + $this->plotarea_width / 2) - (strlen($this->x_axis_label) * 3.5),
					$this->height - 15,
					$this->border_color,
					'cour',				
					$this->x_axis_label
					);
		
		
	
		/* Draw plot borders */
		imageline($this->image,
		$this->width - $this->plotarea_width, 0,
		$this->width - $this->plotarea_width, $this->plotarea_height, $this->border_color);
	
		imageline($this->image,
		$this->width - $this->plotarea_width, $this->plotarea_height,
		$this->width, $this->plotarea_height, $this->border_color);
	
		/* Draw x axis*/
		imageline($this->image,
		$this->width - $this->plotarea_width, $this->x_axis,
		$this->width, $this->x_axis, $this->border_color);
		
		/* Draw y lables, if present */
		if($num_lable = count($this->y_lables))
		{
			reset($this->y_lables);
			
			/* Calculate the space between each label */
			$label_space = $this->plotarea_height / ($num_lable - 1);
			
			for($y = $this->plotarea_height; $y > -1; $y = $y - $label_space)
			{
				$label = current($this->y_lables);
				$left_offset = strlen($label) * 7;
	
				
				
				
				/* Write label string */
				//imagestring($this->image, $this->font,
				//$this->width - $this->plotarea_width - $left_offset - 4, $y - 1,
				//$label, $this->border_color);
				
				imagettftext(
					$this->image,
					$this->font_size,				
					0,
					$this->width - $this->plotarea_width - $left_offset- 12, 
					$y - 1,
					$this->border_color,
					$this->font_name,
					$label
					);	
				
				
				
				
	
				/* Draw Data marker */
				imageline($this->image,
				$this->width - $this->plotarea_width - 2, $y,
				$this->width - $this->plotarea_width, $y,
				$this->border_color);
				
				next($this->y_lables);
			}
		}
		
		/* Draw data lables, if present */
		if($num_lable = count($this->data_lables))
		{
			current($this->data_lables);
	
			/* Calculate the space between each label */
			$label_space = $this->plotarea_width / ($num_lable + 1);
			
			for($x = ($this->width - $this->plotarea_width) + $label_space; $x < $this->width; $x = $x + $label_space)
			{
				$label = current($this->data_lables);
				$left_offset = (strlen($label) * 6) / 2;
	
				/* Write label string */
				imageline($this->image,
				$x, $this->plotarea_height,
				$x, $this->plotarea_height + 2,
				$this->border_color);
	
				/* Draw Data marker */			
				//imagestring($this->image, $this->font,
				//$x - $left_offset, $this->plotarea_height + 4,
				//$label, $this->border_color);
				
				
				imagettftext(
					$this->image,
					$this->font_size,				
					0,
					$x - $left_offset,
					$this->plotarea_height + 15, //+ 4,
					$this->border_color,
					$this->font_name,
					$label
					);	
				
				next($this->data_lables);
			}
		}
	}
	
	/*
	 * ImageColorAllocate($this->image, $red, $green, $blue);
	 */	
	function allocColor($red, $green, $blue)
	{		
		return ImageColorAllocate($this->image, $red, $green, $blue);		
	}
	function whOfCoord()
	{
		
	}
	
	
	
	/*
	 * Plot data to plotted_data 
	 */
	function prep()
	{
		
		/* If data_lables present get spacing from data_lables */
		if($num_lable = count($this->data_lables))
		{
			$label_space = $this->plotarea_width / ($num_lable + 1);
	
		/* If data present get spacing from data */
		}elseif($num_lable = count($this->data)){
			$label_space = $this->plotarea_width / ($num_lable + 1);
	
		}else{
			echo "Error: No data to prepare";
			exit;
		}
	
		reset($this->data);
		$plotted_index = 0;
				
		for($x = ($this->width - $this->plotarea_width) + $label_space; $x < $this->width; $x = $x + $label_space)
		{
			$data_entry = current($this->data);
	
			/* if data_entry off the top of the chart, clip it */
			if($data_entry > $this->y_range_pos)
			{$data_entry = $this->y_range_pos;}
	
			/* if data_entry off the bottom of the chart, clip it */
			if($data_entry < ($this->y_range_neg * -1))
			{$data_entry = $this->y_range_neg * -1;}
			
			if($data_entry >= 0)
			{
				$y = $this->x_axis - ($this->x_axis * ($data_entry / $this->y_range_pos));
	
			}else{
				$y = $this->x_axis + (($this->plotarea_height - $this->x_axis) * (($data_entry  * -1) / $this->y_range_neg));
	
			}
	
			/* Write plotting data to plotted_data variable */
			$this->plotted_data[$plotted_index] = array($x, $y);
	
			$plotted_index++;
			next($this->data);
		}
	}
	
	/*
	 * Plot data to image as solid bars
	 */
	function plot($bar_width = 10)
	{
		reset($this->plotted_data);
		$bar_width = $bar_width / 2;
		
		while(list($x, $y) = current($this->plotted_data))
		{	
	
			if($y < $this->x_axis)
			{
				imagefilledrectangle($this->image,
				$x - $bar_width, $y,
				$x + $bar_width, $this->x_axis,
				$this->graph_color);
				
			}else{
				imagefilledrectangle($this->image,
				$x - $bar_width, $this->x_axis,
				$x + $bar_width, $y,
				$this->graph_color);			
	
			}
			
			next($this->plotted_data);
		}
	}
	
	/*
	 * Save file and free memory
	 */
	function close()
	{
		imagegif($this->image, $this->filename);
		imagedestroy($this->image);
	}

}

/*
 * graphite_line Class extend plot() function 
 */
class graphite_line extends graphite
{
	function plot()
	{
		$count = count($this->plotted_data);
		reset($this->plotted_data);
		$y_last = $this->x_axis;
		list($x_last, $junk) = current($this->plotted_data);
	
		reset($this->plotted_data);
		
		for($i = 0; $i < $count; $i++)
		{
			list($x_next, $y_next) = current($this->plotted_data);
			imageline($this->image,
			$x_next, $y_next,
			$x_last, $y_last,
			$this->graph_color);
			
			$x_last = $x_next;
			$y_last = $y_next;
			
			next($this->plotted_data);
		}
	
		imageline($this->image,
		$x_last, $y_last,
		$x_next, $this->x_axis,
		$this->graph_color);	
	}
}

/*
 * graphite_area Class extend plot() function 
 */
class graphite_area extends graphite
{
	function plot()
	{	
		reset($this->plotted_data);
	
		list($x, $y) = current($this->plotted_data);
		$poly[] = $x;
		$poly[] = $this->x_axis;
	
		reset($this->plotted_data);	
		while(list($x, $y) = current($this->plotted_data))
		{	
			$poly[] = $x;
			$poly[] = $y;
			$x_last = $x;
			next($this->plotted_data);
		}
	
		$poly[] = $x_last;
		$poly[] = $this->x_axis;
	
		imagefilledpolygon($this->image,
		$poly,
		count($poly) / 2,
		$this->graph_color);	
	}
}


/*
 * Returns an array of integers given a range
 */
function xrange($begin, $end, $step = 1)
{
	if($begin > $end)
	{	
		if($step >= 0)	{echo "Error: 'step' argument is positive or zero"; exit;}

		for($i = $begin; $i >= $end; $i = $i + $step)
		{$range[] = $i;}
		
	}
	else
	{
		if($step <= 0){echo "Error: 'step' argument is negitive or zero"; exit;}

		for($i = $begin; $i <= $end; $i = $i + $step)
		{$range[] = $i;}
	}

	return $range;
}
?>